package test.panel4;
import test.CPU.CPUController;
import test.CPU.CPUObserver;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Map;
import java.util.List;
import java.util.Objects;

public class Panel4 extends JPanel implements CPUObserver {
    private static Panel4 instance;
    JPanel left_Panel;
    DefaultListModel<String> listModel;
    JLabel ClockLabel = new JLabel("CPUClock: ");
    JPanel right_Panel;
    JPanel topList;
    JPanel bottomList;

    public static Panel4 getInstance(){
        if(instance != null){
            return instance;
        }
        instance = new Panel4();
        return instance;
    }

    private Panel4(){
        super(new BorderLayout());
        initPanels();

        // 使用 JSplitPane 分割左右两个面板，设置左边占比为30%
        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, left_Panel, right_Panel);
        splitPane.setDividerLocation(0.3); // 设置左侧部分的大小比例
        splitPane.setResizeWeight(0.3); // 调整面板缩放时保持比例
        this.add(splitPane, BorderLayout.CENTER);
    }

    private void initPanels(){
        CPUController.addObserver(this);
        //创建左面板
        left_Panel = new JPanel(new BorderLayout());
        JPanel ltPanel = new JPanel(new BorderLayout());//左面板的上面版
        //下拉列表
        String[] options = {"先来先服务(FCFS)","短作业优先(SJF)","最早截止时间优先(EDF)","最低松弛度优先(LSF)"};
        JComboBox<String> comboBox = new JComboBox<>(options);
        comboBox.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                // Change the attribute value based on selected item
                Control.scheduler = (String) comboBox.getSelectedItem();
            }
        });
        //cpu时钟
        ltPanel.add(ClockLabel,BorderLayout.CENTER);
        ltPanel.add(comboBox,BorderLayout.EAST);
        //进程列表
        listModel = new DefaultListModel<>();
        JList<String> leftList = new JList<>(listModel);
        JScrollPane leftScrollPane = new JScrollPane(leftList);

        left_Panel.add(ltPanel,BorderLayout.NORTH);
        left_Panel.add(leftScrollPane, BorderLayout.CENTER); // 组件填满left_Panel

        //创建右面板
        right_Panel = new JPanel();
        right_Panel.setLayout(new BoxLayout(right_Panel, BoxLayout.Y_AXIS)); // 使用 BoxLayout 垂直排列组件
        //创建上列表
        topList = new JPanel();
        topList.setLayout(new BoxLayout(topList, BoxLayout.Y_AXIS));
        topList.setBorder(BorderFactory.createTitledBorder("运行的进程"));
        JScrollPane topScrollPane = new JScrollPane(topList);
        topScrollPane.setPreferredSize(new Dimension(right_Panel.getSize().width, right_Panel.getSize().height / 2));
        topScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        right_Panel.add(topScrollPane);
        //创建下列表
        bottomList = new JPanel();
        bottomList.setLayout(new BoxLayout(bottomList,BoxLayout.Y_AXIS));
        bottomList.setBorder(BorderFactory.createTitledBorder("挂起的进程"));
        JScrollPane bottomScrollPane = new JScrollPane(bottomList);
        bottomScrollPane.setPreferredSize(new Dimension(right_Panel.getSize().width, right_Panel.getSize().height / 2));
        bottomScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        right_Panel.add(bottomScrollPane);
        // 在上下列表之间插入工具栏
        JToolBar toolBar = new JToolBar();
        toolBar.setFloatable(false); // 禁用浮动
        JButton addProcessButton = new JButton("添加进程");
        addProcessButton.addActionListener(e -> {
            Control.addProcess("进程",false);
        });
        toolBar.add(addProcessButton);
        // 使用一个具有固定高度的面板来容纳工具栏
        JPanel toolbarPanel = new JPanel();
        toolbarPanel.setLayout(new BorderLayout());
        toolbarPanel.add(toolBar, BorderLayout.CENTER);
        toolbarPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, toolBar.getPreferredSize().height)); // 设定最大高度
        right_Panel.add(toolbarPanel);
    }

    public static void addToTop(JPanel panel){
        getInstance().topList.add(panel);
        refreshPanel(getInstance().topList);
    }
    public static void removeFromTop(JPanel panel){
        getInstance().topList.remove(panel);
        refreshPanel(getInstance().topList);
    }
    public static void addToBottom(JPanel panel){
        getInstance().bottomList.add(panel);
        refreshPanel(getInstance().bottomList);
    }
    public static void removeFromBottom(JPanel panel){
        getInstance().bottomList.remove(panel);
        refreshPanel(getInstance().bottomList);
    }

    private static void refreshPanel(JPanel panel) {
        panel.revalidate();
        panel.repaint();
    }

    public static void main(String[] args) {
        CPUController cc = CPUController.getInstance();
        Scheduler ss = Scheduler.getInstance();
        JFrame frame = new JFrame("Panel4 Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(getInstance());
        frame.setSize(800, 600);
        frame.setLocationRelativeTo(null); // 窗口居中
        frame.setVisible(true);
    }
    @Override
    public void CPUUpdate(int clock) {
        SwingUtilities.invokeLater(() -> {
            this.ClockLabel.setText("CPUClock: " + clock);
        });
    }

    public static void updateLeftList() {
        // 创建两个列表来分别存储“运行”和其他状态的进程
        List<String> runningProcesses = new ArrayList<>();
        List<String> otherProcesses = new ArrayList<>();

        // 遍历所有的运行进程
        for (Map.Entry<Integer, Process> entry : Control.running_process.entrySet()) {
            Process p = entry.getValue();
            String processStr = String.valueOf(p);
            if (Objects.equals(p.state, "运行")) {
                runningProcesses.add(processStr);
            } else {
                otherProcesses.add(processStr);
            }
        }
        // 合并两个列表，把“运行”状态的进程放在前面
        List<String> updatedModel = new ArrayList<>(runningProcesses);
        updatedModel.addAll(otherProcesses);
        // 检查模型是否变化，如果变化了就更新JList
        SwingUtilities.invokeLater(() -> {
            getInstance().listModel.clear();
            for (String process : updatedModel) {
                getInstance().listModel.addElement(process);
            }
        });
    }
}

